/******************* (C) COPYRIGHT 2019 Fortiortech Shenzhen *******************
    File Name          : FU68xx_4_FLASH.c
    Creat Author       : Any Lin, R&D
    Modify Author      : Any Lin, R&D
    Creat Date         : 2019-06-08
    Modify Date        : 2019-06-11
    Description        :
********************************************************************************
    All Rights Reserved
*******************************************************************************/

/******************************************************************************/
#include "MyProject.h"
#include <intrins.h>
#include <FU68xx_4_MCU.h>
#include<string.h> 
/******************************************************************************/

POST_TypeDef xdata Fla_Post; /*实际地址=FLA_DATA_START+Save_ADDR*DATA_WIDT*/
Diagnostic Diagnostic_Data;   /*诊断数据*/

/******************************************************************************/
/******************************************************************************/

/*****************************************************************************
    \brief          : 扇区自擦除: 指定将要擦除的Flash扇区，每个扇区128Byte，共128个扇区，
                                    扇区0~127对应Flash地址0x0000~0x3fff，通过指定Flash地址来指定要擦除
                                    的Flash地址所在扇区。一次只能擦除一个扇区，自擦除数据为任意值，一定
                                    要在解锁后才给DPTR赋值。
    \param          : FlashAddress--Flash自擦除扇区内任意地址
    \retval         : 0--Flash自擦除成功，1--Flash自擦除失败
*****************************************************************************/
static uint8 Flash_Sector_Erase(uint16 FlashAddress)
{
    bool TempEA;
    uint16 TempFlashAddress;

    TempFlashAddress = FlashAddress;

    TempEA = EA; //保持当前中断状态
    EA = 0;

    if (FlashAddress < 0x3f80) /*** 不擦除最后一个扇区***/
    {
        FLA_CR = 0x03; /*** 使能自擦除***/
        FLA_KEY = FLA_KEY5A;
        FLA_KEY = FLA_KEY1F; /*** flash预编程解锁***/
        _nop_();
        *(uint8 xdata *)TempFlashAddress = 0xff; /*** 写任意数据***/
        FLA_CR = 0x08;                           /*** 开始预编程，完成后Flash再次上锁***/
    }

    EA = TempEA;

    if (ReadBit(FLA_CR, FLAERR))
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

/*****************************************************************************
    \brief          : Flash自烧写: 对扇区预编程和自擦除后，可以对扇区内的地址进行Flash烧写，
                  一次烧写一个byte,一定要在解锁后才给DPTR赋值
    \param          : FlashAddress--Flash烧写地址
                    : FlashData--Flash烧写数据
    \retval         : 0--Flash自烧写成功，1--Flash自烧写失败
*****************************************************************************/
static uint8 Flash_Sector_Write(uint16 FlashAddress, uint8 FlashData)
{
    bool TempEA;
    //    data uint16 TempFlashAddress;

    //    TempFlashAddress = FlashAddress;
    TempEA = EA;
    EA = 0;
    if (FlashAddress < 0x3f80) /*** 不编程最后一个扇区***/
    {
        FLA_CR = 0x01; /*** 使能Flash编程***/
        FLA_KEY = 0x5a;
        FLA_KEY = 0x1f; /*** flash预编程解锁***/
        _nop_();
        *(uint8 xdata *)FlashAddress = FlashData; /*** 写编程数据***/
        FLA_CR = 0x08;                            /*** 开始预编程，完成后Flash再次上锁***/
    }
    EA = TempEA;

    if (ReadBit(FLA_CR, FLAERR))
    {
        return 0;
    }
    else
    {
        return 1;
    }
}

/*****************************************************************************
    \brief          : 数据读取
    \param          : FlashAddress--数据读取地址
                    : FlashData --  数据存放数组
                    : length    --  读取字节数
    \retval         : 0--Flash读取成功，1--Flash读取失败
*****************************************************************************/
uint8 DataRead(uint16 FlashAddress, uint8 *Data, uint8 length)
{
    data uint16 TempFlashAddress;
    uint8 i = 0;
    if ((FlashAddress + length) > 0x3f80)
        return 0; /*** 地址或数据长度错误***/

    for (i = 0; i < length; i++)
    {
        TempFlashAddress = FlashAddress + i;
        Data[i] = *(uint8 code *)TempFlashAddress;
        ;
    }
    return 1;
}

/*****************************************************************************
    \brief          : 数据写入
    \param          : FlashAddress--数据读取地址
                    : FlashData --  数据写入数组
                    : length    --  写入字节数
    \retval         : 0--Flash写入成功，1--Flash写入失败
*****************************************************************************/
uint8 DataWrite(uint16 FlashAddress, uint8 *Data, uint8 length)
{
    data uint16 TempFlashAddress;
    uint8 i = 0;
    TempFlashAddress = FlashAddress;
    if ((TempFlashAddress + length) > 0x3f80)
        return 0; /*** 地址或数据长度错误***/
    for (i = 0; i < length;)
    {
        if (Flash_Sector_Write(TempFlashAddress, Data[i]))
        {
            i++;
            TempFlashAddress = FlashAddress + i;
        }
    }
    return 1;
}

/*****************************************************************************
    \brief          : Read_Maxpost 读取运行最大角度值
    \param          : None
    \retval         : None
*****************************************************************************/
uint16 Read_Maxpost(void)
{
   
}

/*****************************************************************************
    \brief          : Save_Maxpost 存储运行最大角度值
    \param          : None
    \retval         : None
*****************************************************************************/
void Save_Maxpost(uint16 post)
{
    
}

/*****************************************************************************
    \brief          : Read_Lastpost 读取上次运行值的
    \param          : None
    \retval         : None
*****************************************************************************/
uint16 Read_Lastpost(void)
{
    
}

/*****************************************************************************
    \brief          : Save_Maxpost 存储运行运行值
    \param          : None
    \retval         : None
*****************************************************************************/
void Save_Lastpost(uint16 post)
{
    
}

/*****************************************************************************
    \brief          : Read_Diagnostic 读取诊断数据
    \param          : None
    \retval         : None
*****************************************************************************/
void Read_Diagnostic(void)
{
   
}

/*****************************************************************************
    \brief          : Save_Diagnostic 保存诊断数据 只有在退出诊断或诊断复位时候才进行读写否则无法承受高频次擦写。
    \param          : None
    \retval         : None
*****************************************************************************/
void Save_Diagnostic(void)
{

}


void Save_DATA(void)
{

  
  
}